{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "f9968490",
   "metadata": {},
   "source": [
    "# 字典（dict）\n",
    "\n",
    "## key数据组对应value数据组\n",
    "### 为了保存具有映射关系的数据，Python 提供了字典， 字典相当于保存了两组数据，其中一组数据是关键数据，被称为 key；另一组数据可通过 key 来访问，被称为 value.\n",
    "\n",
    "### 由于字典中的 key 是非常关键的数据，而且程序需要通过 key 来访问 value，因此字典中的 key 不允许重复。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "056d8307",
   "metadata": {},
   "source": [
    "## 1.字典的创建方式\n",
    "* 可使用花括号语法来创建字典，也可使用 dict() 函数来创建字典\n",
    "* 在使用花括号语法创建字典时，花括号中应包含多个 key-value 对，key 与 value 之间用英文冒号隔开；多个 key-value 对之间用英文逗号隔开。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "59341bd7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'语文': 89, '数学': 92, '英语': 93}\n",
      "{}\n",
      "{(20, 30): 'good', 30: 'bad'}\n"
     ]
    }
   ],
   "source": [
    "scores = {'语文': 89, '数学': 92, '英语': 93}\n",
    "print(scores)\n",
    "\n",
    "# 空的花括号代表空的dict\n",
    "empty_dict = {}\n",
    "print(empty_dict)\n",
    "\n",
    "# 使用元组作为dict的key\n",
    "dict2 = {(20, 30):'good', 30:'bad'}\n",
    "print(dict2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "639cd6ad",
   "metadata": {},
   "source": [
    "**元组可以作为 dict 的 key，但列表不能作为元组的 key。这是由于 dict 要求 key 必须是不可变类型，但列表是可变类型，因此列表不能作为元组的 key。**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8bfcb117",
   "metadata": {},
   "source": [
    "#### 在使用 dict() 函数创建字典时，可以传入多个列表或元组参数作为 key-value 对，每个列表或元组将被当成一个 key-value 对，因此这些列表或元组都只能包含两个元素"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "3b248cee",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'celery': 1.58, 'brocoli': 1.29, 'lettuce': 2.19}\n",
      "{'BMW': 8.5, 'BENS': 8.3, 'AUDI': 7.9}\n",
      "{}\n"
     ]
    }
   ],
   "source": [
    "vegetables = [('celery', 1.58), ('brocoli', 1.29), ('lettuce', 2.19)]\n",
    "# 创建包含3组key-value对的字典\n",
    "dict3 = dict(vegetables)\n",
    "print(dict3) # {'celery': 1.58, 'brocoli': 1.29, 'lettuce': 2.19}\n",
    "\n",
    "cars = [['BMW', 8.5], ['BENS', 8.3], ['AUDI', 7.9]]\n",
    "# 创建包含3组key-value对的字典\n",
    "dict4 = dict(cars)\n",
    "print(dict4) # {'BMW': 8.5, 'BENS': 8.3, 'AUDI': 7.9}\n",
    "\n",
    "\n",
    "# 如果不为 dict() 函数传入任何参数，则代表创建一个空的字典\n",
    "# 创建空的字典\n",
    "dict5 = dict()\n",
    "print(dict5) # {}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "37c04868",
   "metadata": {},
   "source": [
    "#### 还可通过为 dict 指定关键字参数创建字典，此时字典的 key 不允许使用表达式"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "0790cc7e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'spinach': 1.39, 'cabbage': 2.59}\n"
     ]
    }
   ],
   "source": [
    "# 使用关键字参数来创建字典\n",
    "dict6 = dict(spinach = 1.39, cabbage = 2.59)\n",
    "print(dict6) # {'spinach': 1.39, 'cabbage': 2.59}\n",
    "\n",
    "# 上面粗体字代码在创建字典时，其 key 直接写 spinach、cabbage，不需要将它们放在引号中"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ee918aef",
   "metadata": {},
   "source": [
    "## 2.字典的基本用法"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f90899c9",
   "metadata": {},
   "source": [
    "* 通过 key 访问 value 。\n",
    "* 通过 key 添加 key-value 对。\n",
    "* 通过 key 删除 key-value 对。\n",
    "* 通过 key 修改 key-value 对。\n",
    "* 通过 key 判断指定 key-value 对是否存在。\n",
    "* 通过 key 访问 value 使用的也是方括号语法，就像前面介绍的列表和元组一样，只是此时在方括号中放的是 key，而不是列表或元组中的索引。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "06505e97",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "90\n"
     ]
    }
   ],
   "source": [
    "# 通过 key访问 value\n",
    "scores = {'语文': 90}\n",
    "print(scores['语文'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "9645f714",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'语文': 90, '数学': 85, 92: 6.6}\n"
     ]
    }
   ],
   "source": [
    "# 通过 key 添加 key-value 对\n",
    "# 如果要为 dict 添加 key-value 对，只需为不存在的 key 赋值即可\n",
    "# 对不存在的key赋值，就是增加key-value对\n",
    "scores['数学']= 85\n",
    "scores[92] = 6.6\n",
    "print(scores)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "9e658cc0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'数学': 85}\n"
     ]
    }
   ],
   "source": [
    "# 通过 key 删除 key-value 对。\n",
    "# 如果要删除字典中的 key-value 对，则可使用 del 语句\n",
    "# 使用del语句删除key-value对\n",
    "del scores['语文']\n",
    "del scores[92]\n",
    "print(scores)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "177d4e9b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'banana': 5.5, 'apple': 6, 'orange': 2.5}\n"
     ]
    }
   ],
   "source": [
    "# 通过 key 修改 key-value 对\n",
    "# 如果对 dict 中存在的 key-value 对赋值，新赋的 value 就会覆盖原有的 value，这样即可改变 dict 中的 key-value 对\n",
    "\n",
    "fruit = {'banana':5.5, 'apple':4.3,'orange':3.2}\n",
    "# 对存在的key-value对赋值，改变key-value对\n",
    "fruit['apple'] = 6\n",
    "fruit['orange'] = 2.5\n",
    "print(fruit)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "f65dea68",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "# 通过 key 判断指定 key-value 对是否存在\n",
    "# 如果要判断字典是否包含指定的 key，则可以使用 in 或 not in 运算符。\n",
    "# 需要指出的是，对于 dict 而言，in 或 not in 运算符都是基于 key 来判断的。\n",
    "\n",
    "print('banana' in fruit) # 判断fruit是否包含名为'banana'的key\n",
    "print('watermelon' in fruit) # 判断fruit是否包含名为'watermelon'的key\n",
    "print('strawberry' not in fruit)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1b20f696",
   "metadata": {},
   "source": [
    "## 3. 字典的常用用法\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cc55759d",
   "metadata": {},
   "source": [
    "* clear()方法\n",
    "##### clear() 用于清空字典中所有的 key-value 对，对一个字典执行 clear() 方法之后，该字典就会变成一个空字典"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "7e7f91f9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'banana': 5.5, 'apple': 4.3, 'orange': 3.2}\n",
      "{}\n"
     ]
    }
   ],
   "source": [
    "fruit = {'banana':5.5, 'apple':4.3,'orange':3.2}\n",
    "print(fruit)\n",
    "\n",
    "# 清空fruit所有key-value对\n",
    "fruit.clear()\n",
    "print(fruit)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4ad6c44f",
   "metadata": {},
   "source": [
    "* get()方法\n",
    "##### get() 方法其实就是根据 key 来获取 value，它相当于方括号语法的增强版"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "b247ae54",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4.3\n",
      "None\n"
     ]
    }
   ],
   "source": [
    "fruit = {'banana':5.5, 'apple':4.3,'orange':3.2}\n",
    "\n",
    "# 获取'apple'对应的value\n",
    "print(fruit.get('apple'))\n",
    "\n",
    "# 当使用方括号语法访问并不存在的 key 时，字典会引发 KeyError 错误\n",
    "# print(fruit['watermelon'])\n",
    "\n",
    "# 但如果使用 get() 方法访问不存在的 key，该方法会简单地返回 None，不会导致错误\n",
    "print(fruit.get('watermelon'))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f21da8d5",
   "metadata": {},
   "source": [
    "* update()方法\n",
    "##### update() 方法可使用一个字典所包含的 key-value 对来更新己有的字典。\n",
    "##### 在执行 update() 方法时，如果被更新的字典中己包含对应的 key-value 对，那么原 value 会被覆盖；\n",
    "##### 如果被更新的字典中不包含对应的 key-value 对，则该 key-value 对被添加进去"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "eedac209",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'banana': 5.5, 'apple': 4.3, 'orange': 2.4, 'strawberry': 6.6}\n"
     ]
    }
   ],
   "source": [
    "fruit = {'banana':5.5, 'apple':4.3,'orange':3.2}\n",
    "fruit.update({'orange':2.4, 'strawberry':6.6})\n",
    "print(fruit)\n",
    "# 由于被更新的 dict 中己包含 key 为“AUDI”的 key-value 对，因此更新时该 key-value 对的 value 将被改写；\n",
    "# 但如果被更新的 dict 中不包含 key 为“PORSCHE”的 key-value 对，那么更新时就会为原字典增加一个 key-value 对。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a6727426",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
